const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')
const { query, transaction } = require('../config/database')
const CryptoUtils = require('../utils/crypto')
const Validator = require('../utils/validator')
const logger = require('../config/logger')

class AuthController {
  // 生成验证码
  async getCaptcha(req, res) {
    try {
      // 生成验证码
      const captcha = CryptoUtils.generateCaptcha({
        size: 4,
        noise: 2,
        color: true,
        background: '#f0f0f0'
      })
      
      // 生成验证码ID
      const captchaId = CryptoUtils.generateUUID()
      
      // 存储验证码到数据库（5分钟过期）
      const expiresAt = new Date(Date.now() + 5 * 60 * 1000) // 5分钟后过期
      
      await query(`
        INSERT INTO captcha_codes (captcha_id, code, expires_at) 
        VALUES (?, ?, ?)
      `, [captchaId, captcha.text.toLowerCase(), expiresAt])
      
      // 清理过期的验证码
      await query(`
        DELETE FROM captcha_codes 
        WHERE expires_at < NOW() OR used = 1
      `)
      
      logger.info(`验证码生成成功: ${captchaId}`)
      
      res.success({
        captcha_id: captchaId,
        captcha_image: `data:image/svg+xml;base64,${Buffer.from(captcha.data).toString('base64')}`
      }, '验证码生成成功')
      
    } catch (error) {
      logger.error('生成验证码失败:', error)
      res.error('生成验证码失败', 500)
    }
  }
  
  // 验证验证码
  async verifyCaptcha(captchaId, captchaCode) {
    try {
      const result = await query(`
        SELECT * FROM captcha_codes 
        WHERE captcha_id = ? AND used = 0 AND expires_at > NOW()
      `, [captchaId])
      
      if (result.length === 0) {
        return { valid: false, message: '验证码已过期或不存在' }
      }
      
      const captcha = result[0]
      if (captcha.code !== captchaCode.toLowerCase()) {
        return { valid: false, message: '验证码错误' }
      }
      
      // 标记验证码为已使用
      await query(`
        UPDATE captcha_codes SET used = 1 WHERE captcha_id = ?
      `, [captchaId])
      
      return { valid: true, message: '验证码正确' }
      
    } catch (error) {
      logger.error('验证码验证失败:', error)
      return { valid: false, message: '验证码验证失败' }
    }
  }
  
  // 用户注册
  async register(req, res) {
    try {
      const { username, password, captcha_code, captcha_id, phone, email, name } = req.body
      
      // 参数验证
      const validation = Validator.validate({
        username: { required: true, length: [3, 20] },
        password: { required: true, length: [6, 20] },
        captcha_code: { required: true, length: [4, 4] },
        captcha_id: { required: true }
      }, req.body)
      
      if (!validation.success) {
        return res.error(validation.message, 400)
      }
      
      // 验证码验证
      const captchaResult = await this.verifyCaptcha(captcha_id, captcha_code)
      if (!captchaResult.valid) {
        return res.error(captchaResult.message, 400)
      }
      
      // 检查用户名是否已存在
      const existingUser = await query(
        'SELECT id FROM users WHERE username = ?',
        [username]
      )
      
      if (existingUser.length > 0) {
        return res.error('用户名已存在', 400)
      }
      
      // 加密密码
      const hashedPassword = await CryptoUtils.hashPassword(password)
      
      // 创建用户
      const result = await query(`
        INSERT INTO users (username, password, phone, email, name, role, status) 
        VALUES (?, ?, ?, ?, ?, 'employee', 1)
      `, [username, hashedPassword, phone || null, email || null, name || username])
      
      const userId = result.insertId
      
      logger.info(`用户注册成功: ${username} (ID: ${userId})`)
      
      res.success({
        user_id: userId,
        username: username
      }, '注册成功')
      
    } catch (error) {
      logger.error('用户注册失败:', error)
      
      if (error.code === 'ER_DUP_ENTRY') {
        return res.error('用户名或手机号已存在', 400)
      }
      
      res.error('注册失败', 500)
    }
  }
  
  // 用户登录
  async login(req, res) {
    try {
      const { username, password, captcha_code, captcha_id } = req.body
      
      // 参数验证
      const validation = Validator.validate({
        username: { required: true },
        password: { required: true },
        captcha_code: { required: true },
        captcha_id: { required: true }
      }, req.body)
      
      if (!validation.success) {
        return res.error(validation.message, 400)
      }
      
      // 验证码验证
      const captchaResult = await this.verifyCaptcha(captcha_id, captcha_code)
      if (!captchaResult.valid) {
        return res.error(captchaResult.message, 400)
      }
      
      // 查找用户
      const users = await query(`
        SELECT id, username, password, name, phone, email, role, status, created_at 
        FROM users 
        WHERE username = ?
      `, [username])
      
      if (users.length === 0) {
        return res.error('用户名或密码错误', 400)
      }
      
      const user = users[0]
      
      // 检查用户状态
      if (user.status !== 1) {
        return res.error('账号已被禁用', 400)
      }
      
      // 验证密码
      const passwordValid = await CryptoUtils.comparePassword(password, user.password)
      if (!passwordValid) {
        return res.error('用户名或密码错误', 400)
      }
      
      // 生成JWT token
      const token = CryptoUtils.generateToken({
        userId: user.id,
        username: user.username,
        role: user.role
      })
      
      // 更新最后登录时间
      await query(`
        UPDATE users SET last_login_at = NOW() WHERE id = ?
      `, [user.id])
      
      // 记录登录日志
      logger.info(`用户登录成功: ${username} (ID: ${user.id})`)
      
      // 返回用户信息（不包含密码）
      delete user.password
      
      res.success({
        token: token,
        user: user
      }, '登录成功')
      
    } catch (error) {
      logger.error('用户登录失败:', error)
      res.error('登录失败', 500)
    }
  }
  
  // 获取当前用户信息
  async getCurrentUser(req, res) {
    try {
      const userId = req.user.userId
      
      const users = await query(`
        SELECT id, username, name, phone, email, role, status, created_at, last_login_at
        FROM users 
        WHERE id = ?
      `, [userId])
      
      if (users.length === 0) {
        return res.error('用户不存在', 404)
      }
      
      res.success(users[0], '获取用户信息成功')
      
    } catch (error) {
      logger.error('获取用户信息失败:', error)
      res.error('获取用户信息失败', 500)
    }
  }
  
  // 修改密码
  async changePassword(req, res) {
    try {
      const { old_password, new_password } = req.body
      const userId = req.user.userId
      
      // 参数验证
      const validation = Validator.validate({
        old_password: { required: true },
        new_password: { required: true, length: [6, 20] }
      }, req.body)
      
      if (!validation.success) {
        return res.error(validation.message, 400)
      }
      
      // 获取用户当前密码
      const users = await query(`
        SELECT password FROM users WHERE id = ?
      `, [userId])
      
      if (users.length === 0) {
        return res.error('用户不存在', 404)
      }
      
      // 验证旧密码
      const passwordValid = await CryptoUtils.comparePassword(old_password, users[0].password)
      if (!passwordValid) {
        return res.error('原密码错误', 400)
      }
      
      // 加密新密码
      const hashedNewPassword = await CryptoUtils.hashPassword(new_password)
      
      // 更新密码
      await query(`
        UPDATE users SET password = ?, updated_at = NOW() WHERE id = ?
      `, [hashedNewPassword, userId])
      
      logger.info(`用户修改密码成功: ID ${userId}`)
      
      res.success(null, '密码修改成功')
      
    } catch (error) {
      logger.error('修改密码失败:', error)
      res.error('修改密码失败', 500)
    }
  }
  
  // 用户登出
  async logout(req, res) {
    try {
      // 这里可以实现token黑名单机制
      // 目前客户端删除token即可
      
      logger.info(`用户登出: ID ${req.user.userId}`)
      
      res.success(null, '登出成功')
      
    } catch (error) {
      logger.error('用户登出失败:', error)
      res.error('登出失败', 500)
    }
  }
}

module.exports = new AuthController() 